自动化创建

Zero Ai安装

初始化工程之前先安装 Zero Ai工具,该工具提供了不同初始化工程的命令,可一键生成模板。

# 旧版
$ sudo npm install -g vertx-ai
# 新版
$ sudo npm install -g zero-ai

初始化完成之后既可执行工程初始化命令分别初始化:后端、前端、后端插件(现阶段只支持三种类型)。

Ai工具初始化

您可以直接下载 scaffold-zero 后端工程脚手架项目,然后手工修改。 也可以直接运行下边命令进行后端工程初始化:

# n=参数代表后端工程名称以及目录名称
# 请选择不带 `.git` 或 `scaffold-zero` 的目录执行当前命令,最好使用空目录
$ aj init -n <name>

您可以直接下载 scaffold-ui 前端工程脚手架项目,然后手工修改。 也可以直接运行下边命令进行前端工程初始化:

# n=参数代表前端工程名称以及目录名称
# 请选择不带 `.git` 或 `scaffold-ui` 的目录执行当前命令,最好使用空目录
$ ai init -n <name>

后端插件初始化执行运行下边命令:

# m=模块名称,c=配置文件路径,p=工作路径
# -c 和 -p 两个参数可选
$ aj plugin -m <name> -c <workspace.json> -p <path>

Cloud工具集

您可以自己搭建云端开发环境,也可直接下载 Cloud工具箱 云端工具包执行云端工程的辅助开发。

$ git clone git@gitee.com:silentbalanceyh/vertx-zero-cloud.git

推荐您先下载 Cloud工具箱,其中包含了很多一键式自动化脚本以及云端开发的专用目录结构,本文后续章节全部依托该项目执行相关命令。Zero Cloud核心规范全部位于地址 Zero Aeon Cloud专用数据规范,该站点中包含了所有针对配置数据、定义的配置描述,系统可依赖它做配置、模型、定义以及元数据的各种校验。

Cloud在部署基础设施(Docker Compose模式)时,有三个脚本文件:

文件后缀(不带扩展) 含义

@up

执行docker-compose up -d

@down

执行docker-compose down

@stop

执行docker-compose stop

Ansible环境初始化

基本步骤

新版Zero使用了Ansible为开发人员准备一致性开发环境,但基础准备工作需要在此处特殊说明,开发环境的Ansible执行流程图如下:

Fork

Ansible基本准备工作如下:

  1. 目标机器(开发环境本地,生产环境服务器)需配置三个核心命令:mysql、mvn、java(开发环境初始化只需要mysql,java、mvn为将来准备着)。

  2. 由于Ansible使用登录方式为Non Shell,所以上述三个核心命令的配置需要配置在目标机器的 ~/.bashrc 环境变量文件中,如:

    # Ansible ------------------------------------------------------------------
    # Ansible Java
    export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home
    export CLASSPATH=.
    export PATH=$PATH:$JAVA_HOME/bin
    # Ansible Homebrew
    # - MySQL, Maven .....
    export PATH=$PATH:/opt/homebrew/bin
  3. 再执行 ansible 命令的机器配置 /etc/ansible/hosts 设置需操作的主机信息,如:

    [zero]
    ox.engine.cn            # 该地址也已经写入本机host中:127.0.0.1 -> ox.engine.cn

从流程图上可知,前半部分 账号初始化、库初始化 在生产环境和开发环境是一致的,都是使用SSH登录到目标机器执行脚本(Windows会重新开发),后半部分 表初始化、数据初始化 在开发环境使用 liquibase、iac-load.jar 直接执行,而在生产环境则会将初始化内容打包成发布专用的SQL文件,直接执行。

插件指令程序

上述流程中有一个后期指令集的功能,但图上只列举了常用的数据导入部分,开发过程中现阶段支持三个指令程序:

iac 的全称:Infrastructure As Code,inst 的全称:单词指令:Instruction 的缩写。

插件指令程序是为当前应用做所有容器启动前的预处理配置专用,一旦数据库准备好之后,您就可以直接运行所有的插件指令程序完成所需的操作。

名称 说明

inst-load.jar

配置数据导入器,负责所有现存配置数据的导入流程。

inst-atom.jar

建模管理器,负责所有动态建模数据的导入(需在环境变量中设置:DB_ATOM=true )。

inst-menu.jar

菜单规划器,负责所有菜单的重命名、排序、父子级连接。

有了 菜单规划器 之后,新版本的程序导入不需要导入菜单中的 ORDER(排序)、PARENT_ID(父子级关系)、TEXT(菜单名称)、LEVEL(菜单等级) 等核心字段,这样Excel配置文件中的菜单数据就彻底被简化了。

所有的 指令程序 都是可以独立运行的,您也可以直接找到对应的 main 函数作为单独的 Java Console 程序去执行,最终产生的效果都是一致的,Zero 中针对大量的程序执行做过 幂等性 处理,所以您也不用担心反复执行带来的副作用问题。 :data-uri:

数据库环境(开发)

本章节主要讲解Zero中数据库初始化流程,默认账号密码如:

类型 账号 说明

MySQL / TiDB

root

root账号

MySQL / TiDB

zero

核心管理员账号

由于做过脱敏的处理,MySQL 需要您在自己运行的机器上配置 免密码 登录的模式来执行Zero Extension的数据库交互脚本,这样的模式下不依赖环境变量,但更安全,不过这种模式仅用于 Zero 的研发过程而不是开发过程。

MySQL 8.0

Docker-Compose

进入到zone@docker/database-dc-mysql-8目录中,该目录中包含了MySQL的Docker-Compose基础配置,为了脱敏操作,下载的版本中没有环境变量文件 zero-mysql-8.env,您可以直接将目录中的模板文件拷贝一份:

$ cd zone@docker/database-dc-mysql-8
$ cp tpl.zero-mysql-8.env zero-mysql-8.env

使用工具或IDE编辑您两个账号的初始密码:

MYSQL_ROOT_PASSWORD=
MYSQL_ROOT_HOST=%
MYSQL_USER=zero
MYSQL_PASSWORD=
参数 含义

MYSQL_ROOT_PASSWORD

root账号密码

MYSQL_ROOT_HOST

root账号访问的host设置,最终为 root@host中host部分

MYSQL_USER

新建MySQL账号名

MYSQL_PASSWORD

新建MySQL账号对应密码(初始化执行即为zero账号授权)

然后执行如下命令启动MySQL:

$ ./zero-mysql-8-@up.sh

运行成功后,您可以使用工具连接MySQL(确认zero/root双账号可连接)。

$ mysql -u zero -P 3306 -h ox.engine.cn
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.27 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

确认您的 zero 账号执行过 init 下的初始化脚本,该脚本会为 zero 账号执行授权,您可以在MySQL中查看该账号是否授权成功。

Terraform

进入到zone@terraform目录中,该目录中包含了MySQL的所有terraform脚本,为了脱敏操作,下载版本中没有设置环境变量文件 initialize.sh,您可以直接将目录中的 tpl.initialize.sh 拷贝一份:

$ cd zone@terraform/kmini/database-mysql-8
$ cp tpl.initialize.sh initialize.sh

使用工具或IDE编辑您两个账号的初始密码,编辑 initialize.sh(属性同上,此处不累赘)。

#!/usr/bin/env bash
export TF_VAR_mysql_password=
export TF_VAR_mysql_root_password=
export TF_VAR_mysql_data_path=${PWD}/data

# 编辑完成后执行
$ source ./initialize.sh

然后在目录中依次执行下边命令:

# 初始化所有资源
$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding kreuzwerker/docker versions matching "3.0.1"...
- Installing kreuzwerker/docker v3.0.1...
- Installed kreuzwerker/docker v3.0.1 (self-signed, key ID BD080C4571C6104C)

Partner and community providers are signed by their developers.
If you''d like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

# 查看执行计划
$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # docker_container.terraform-mysql-8 will be created
  + resource "docker_container" "terraform-mysql-8" {
      + attach                                      = false
      + bridge                                      = (known after apply)
      + command                                     = (known after apply)
      + container_logs                              = (known after apply)
      + container_read_refresh_timeout_milliseconds = 15000
      + entrypoint                                  = (known after apply)
      + env                                         = [
          + "MYSQL_PASSWORD=xxxxxx123YH",
          + "MYSQL_ROOT_HOST=%",
          + "MYSQL_ROOT_PASSWORD=xxxxxxijn123",
          + "MYSQL_USER=zero",
        ]
      + exit_code                                   = (known after apply)
      + hostname                                    = "ox.engine.cn"
      + id                                          = (known after apply)
      + image                                       = "mysql:8.0.32"
      + init                                        = (known after apply)
      + ipc_mode                                    = (known after apply)
      + log_driver                                  = (known after apply)
      + logs                                        = false
      + must_run                                    = true
      + name                                        = "terraform-mysql-8"
      + network_data                                = (known after apply)
      + read_only                                   = false
      + remove_volumes                              = true
      + restart                                     = "no"
      + rm                                          = false
      + runtime                                     = (known after apply)
      + security_opts                               = (known after apply)
      + shm_size                                    = (known after apply)
      + start                                       = true
      + stdin_open                                  = false
      + stop_signal                                 = (known after apply)
      + stop_timeout                                = (known after apply)
      + tty                                         = false
      + wait                                        = false
      + wait_timeout                                = 60

      + healthcheck {
          + interval     = (known after apply)
          + retries      = (known after apply)
          + start_period = (known after apply)
          + test         = (known after apply)
          + timeout      = (known after apply)
        }

      + labels {
          + label = (known after apply)
          + value = (known after apply)
        }

      + networks_advanced {
          + aliases = []
          + name    = "mysql_network"
        }

      + ports {
          + external = 3306
          + internal = 3306
          + ip       = "0.0.0.0"
          + protocol = "tcp"
        }

      + upload {
          + content    = <<-EOT
                GRANT ALL PRIVILEGES ON *.* TO 'zero'@'%';
                FLUSH PRIVILEGES;
            EOT
          + executable = true
          + file       = "/docker-entrypoint-initdb.d/account.sql"
        }
    }

  # docker_image.mysql will be created
  + resource "docker_image" "mysql" {
      + id           = (known after apply)
      + image_id     = (known after apply)
      + keep_locally = true
      + name         = "mysql:8.0.32"
      + repo_digest  = (known after apply)
    }

  # docker_network.private_network will be created
  + resource "docker_network" "private_network" {
      + driver      = (known after apply)
      + id          = (known after apply)
      + internal    = (known after apply)
      + ipam_driver = "default"
      + name        = "mysql_network"
      + options     = (known after apply)
      + scope       = (known after apply)

      + ipam_config {
          + aux_address = (known after apply)
          + gateway     = (known after apply)
          + ip_range    = (known after apply)
          + subnet      = (known after apply)
        }
    }

Plan: 3 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

# 部署
$ terraform apply

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

docker_network.private_network: Creating...
docker_image.mysql: Creating...
docker_image.mysql: Creation complete after 0s [id=sha256:05b458cc32b9686508b97ef40043702c18572840f7b2936b14f06500363868bamysql:8.0.32]
docker_network.private_network: Creation complete after 2s [id=b6285a9e627492f19fcd001830ddd04a6af1e5df4a6c6aeb501ab0965ce6cf45]
docker_container.terraform-mysql-8: Creating...
docker_container.terraform-mysql-8: Creation complete after 1s [id=b651230638dd8bd576b5ac54bd2edca751154ddafcfd12b1201da6be0e1956e6]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

上述命令执行完成后,您就可以使用客户端连接新的MySQL容器了。

先确认您使用Docker Compose运行的MYSQL容器已经停止运行 docker-compose …​ stop,再执行Terraform版本,由于两个版本使用了相同的宿主机3306端口号,若不停止运行可能会导致创建失败,细心的您会发现Terraform模式下的MySQL并未指定数据目录和日志目录,原因是此处只是为了开发环境使用,详细用法参考 valumes,若您想要删除资源可直接使用下边命令:

terraform destroy

本章节是第一次使用terraform,所以在代码部分我保留了三次执行结果,后续章节再使用terraform时我则会直接忽略不再提供执行结果!

最后还有一个点需要注意,就是 providers.tf 中的代码,由于我使用的MacOS平台,所以此处的值要根据您运行Docker的平台有所变化:

provider "docker" {
  host = "unix:///private/var/run/docker.sock"
}

PgSQL

  • 由于MySQL 5.x和8.x差距比较大,所以才在文件目录中带上了版本号,PgSQL则不需使用版本号标识,直接换镜像名称既可。

  • 如果您使用的是MacOS系统,您可以直接安装 Postgres.app 运行PgSQL(绿色软件)。

Docker-Compose

进入到zone@docker/database-dc-pgsql目录中,该目录中包含了PgSQL的Docker-Compose基础配置,为了脱敏操作,下载的版本中没有环境变量文件 zero-pgsql.env,您可以直接将目录中的模板文件拷贝一份:

$ cd zone@docker/database-dc-pgsql
$ cp tpl.zero-pgsql.env zero-pgsql.env

使用工具或IDE编辑您账号的初始密码:

POSTGRES_PASSWORD=
POSTGRES_USER=postgres
POSTGRES_DB=postgres
TZ=Asia/Shanghai
参数 含义

POSTGRES_PASSWORD

postgres账号密码

POSTGRES_USER

默认账号名

POSTGRES_DB

默认账号访问的Schema名

TZ

默认使用的时区

然后执行如下命令启动PgSQL:

$ ./zero-pgsql-@up.sh
Terraform

进入到zone@terraform目录中,该目录中包含了PgSQL的所有terraform脚本,为了脱敏操作,下载版本中没有设置环境变量文件 initialize.sh,您可以直接将目录中的 tpl.initialize.sh 拷贝一份:

$ cd zone@terraform/kmini/database-pgsql
$ cp tpl.initialize.sh initialize.sh

使用工具或IDE编辑您两个账号的初始密码,编辑 initialize.sh(属性同上,此处不累赘)。

#!/usr/bin/env bash
export TF_VAR_pgsql_password=
export TF_VAR_pgsql_data_path=${PWD}/data

# 编辑完成后执行
$ source ./initialize.sh

然后在目录中依次执行下边命令就可以部署好PgSQL的Docker版本了:

$ terraform init
$ terraform plan
$ terraform apply

注意 main.tf 中关于网络的代码:

resource "docker_network" "private_network" {
  name = "mysql_network"
}

如果只部署一个是没有问题的,但若在同一个Docker中同时运行MySQL和PgSQL,此处需要修改

resource "docker_network" "mysql_network" {
  name = "mysql_network"
}

否则:Docker 容器无法定位网络使用的哪一个导致 terraform apply命令执行失败!

TiDB

Docker Compose

TiDB的Docker Compose版本已经在Cloud工具箱中存在,您可以直接进入zone@docker/database-dc-tidb启动TiDB集群,但由于该集群所需资源比较高昂,所以不建议使用DC方式运行TiDB,当然您机器性能很好就另当别论,最好确认 14个容器 全部在Docker中正常启动,再使用才不会有问题。

TiUP启动

TiDB官方提供了两种快速上手模式(开发环境和生产环境单机运行就不用考虑了,参考 软硬件环境需求 )。直接进入zone@os/database-os-tidb目录中,先更新TiUP Cluster的所有组件:

$ tiup update --self && tiup update cluster

然后直接运行启动脚本:

# tiup playground v6.5.0 --db 2 --pd 3 --kv 3 --tag tidb-zero
$ ./tidb-start.sh
tiup is checking updates for component playground ...
Starting component `playground`: /Users/lang/.tiup/components/playground/v1.11.2/tiup-playground v6.5.0 --db 2 --pd 3 --kv 3 --tiflash 0 --tag tidb-zero
Playground Bootstrapping...
Start pd instance:v6.5.0
Start pd instance:v6.5.0
Start pd instance:v6.5.0
Start tikv instance:v6.5.0
Start tikv instance:v6.5.0
Start tikv instance:v6.5.0
Start tidb instance:v6.5.0
Start tidb instance:v6.5.0
Waiting for tidb instances ready
127.0.0.1:4000 ... Done
127.0.0.1:4001 ... Done
CLUSTER START SUCCESSFULLY, Enjoy it ^-^
To connect TiDB: mysql --comments --host 127.0.0.1 --port 4001 -u root -p (no password)
To connect TiDB: mysql --comments --host 127.0.0.1 --port 4000 -u root -p (no password)
To view the dashboard: http://127.0.0.1:2379/dashboard
PD client endpoints: [127.0.0.1:2379 127.0.0.1:2382 127.0.0.1:2384]
To view the Prometheus: http://127.0.0.1:9090
To view the Grafana: http://127.0.0.1:3000

看到上边界面后就可以直接连接4000端口进入TiDB了(默认root密码"")。

数据导入

配置数据导入是Zero框架中的重头戏,所以单独开章节并且放到项目初始化流程中讲解,只有数据完整导入之后,您的容器启动后才拥有了 配置数据,没有配置数据的容器启动只是一个空壳,无法启用Zero Extension扩展框架中很多便携的功能。开发模式 下数据导入要注意运行的 Working directory 属性,参考 容器启动,否则您将无法导入数据。

目录规范

通常Zero中的数据导入目录分两种:启动器级别模块级别

启动器

启动器的数据一般位于如下目录:

环境 目录地址

Development(开发)

src/main/resources/init/oob/

Mockito(测试)

src/test/resources/init/oob/

Production(生产)

init/oob(即运行程序当前目录下,若是标准编译则位于 conf/init/oob 目录)

数据文件全部位于上述目录中,根据自身环境而定,所有数据文件格式都是 Excel 格式,模板可参考Zero教程: 二向箔: Excel,程序执行过程中会直接使用 init/oob 作为参数,系统自动计算根目录。

最终,只要是合法的Excel模板文件,都会被直接导入到系统数据表中

模块级

如果使用了Zero中的模块化架构,则模块内部的文件结构通常如下:

0

每个模块都有自己独立的目录名称,通常是 zero-xx 后边的 xx,为了遵循扩展规范,后续您创建的新模块目录名尽可能不与这些名称冲突,冲突后可能导致配置文件失效。

  1. 每个模块都会包含一个 plugin/xxx/oob 路径,该路径下的数据文件会被导入到环境中。

  2. 二向箔: Excel 教程中的模块级Excel配置全部位于 initialize.yml 文件中,文件内容如:

    - dao: cn.vertxup.ambient.domain.tables.daos.XSourceDao   # X_SOURCE
      key: key
      unique:
        - appId
    - dao: cn.vertxup.ambient.domain.tables.daos.XAppDao      # X_APP
      key: key
      unique:
        - name
    # .....
  3. 只有在 initialize.json 文件中注册过的数据文件可被导入到环境中,否则系统依然会忽略相关数据文件,内容如:

    [
        "plugin/ambient/oob/cab/ambient.app.xlsx",
        "plugin/ambient/oob/cab/system.document.xlsx",
        "plugin/ambient/oob/cab/system.sync_log.xlsx",
        "plugin/ambient/oob/cab/x.activity.xlsx",
        "....",
    ]

AI工具中的 aj mod 可以根据 oob 目录路径自动写入数据到 initialize.json 中执行注册。

虽然模块中包含了数据目录、链接文件等相关信息,您依旧可以在启动器的同名路径下追加目录和文件,追加的目录和文件会直接覆盖模块级(模块优先级会被启动目录下的内容覆盖),最终形成的拓扑结构如下:

0

  1. 启动器中若不定义任何配置文件,则直接使用模块级配置。

  2. 启动器中的Excel导入导出一旦打开,则会自动链接模块级 initialize.yml 配置文件(保证每张表的配置只在全局环境中出现一次)。

  3. aj mod 命令可以帮助模块做模块级配置,根据数据文件写 initialize.json 配置,参考如:

    aj mod -p src/main/resources/plugin/xxx/oob

模块数据导入配置已经从 Extension 转移到了根路径中的 vertx.yml 配置,0.9.0 版本之后直接使用新配置(本文只讲解新配置,注意类名变化):

# 「模块配置导入」-----------------------------------------------------------------------
boot:
  component:
    on: io.vertx.up.lightway.OnBoot
  config:
    on: io.vertx.up.lightway.OnBootConfig
  extension:
    - executor: io.vertx.mod.ambient.booter.AmbientOOB
    - executor: io.vertx.mod.rbac.booter.RbacOOB
    - executor: io.vertx.mod.erp.booter.ErpOOB
    - executor: io.vertx.mod.psi.booter.PsiOOB
    - executor: io.vertx.mod.fm.booter.FmOOB
    - executor: io.vertx.mod.ui.booter.UiOOB
    - executor: io.vertx.mod.jet.booter.JetOOB
    - executor: io.vertx.mod.graphic.booter.GraphicOOB
    - executor: io.vertx.mod.atom.booter.AtomOOB
    - executor: io.vertx.mod.lbs.booter.LbsOOB
    - executor: io.vertx.mod.workflow.booter.WfOOB
    - executor: io.vertx.mod.is.booter.IsOOB
    - executor: io.vertx.mod.battery.booter.BatteryOOB
    - executor: io.vertx.mod.tpl.booter.TplOOB    # 新版Tpl

上述Java类的定义代码如下:

package io.vertx.mod.ambient.booter;

import io.vertx.mod.ke.cv.KeIpc;
import io.vertx.up.plugin.booting.AbstractBoot;

public class AmbientOOB extends AbstractBoot {
    public AmbientOOB() {
        super(KeIpc.Module.AMBIENT);
    }
}

若您不想启用Zero Extension模块的内容,就不用在 vertx.yml 中配置扩展模块导入器( extension 节点),如此您在执行导入程序时就会跳过OOB数据配置。您若想导入自己的数据,有两种做法:

  1. 按照白皮书中的模块化架构,使用本章导入数据规范开发新的 AbstractBoot 组件,执行本章的模块化配置。

  2. 若您的功能不想做成模块化,直接将数据文件放到启动器的 init/oob 目录中,并按照Zero标准教程中配置对应的Excel导入/导出功能。

规则:Excel单元格

若您在Excel单元格中填写如下:

JSON:authority/auth.menu/ui.surface.json

该单元格会被导入成JSON格式:

0

上述规则会让单元格关联JSON文件做导入:

0

此规则的优点有两个:

  1. 单元格内如果出现了配置重复,可让该单元格引用同一个配置文件,一改既改,这样配置数据很容易维护。

  2. JSON格式不用直接填写在Excel中,而是用外联文件,可压缩Excel的体积,让Excel可读性增强。

规则:默认值/限制/转换

Zero为导入程序提供了一个环境数据文件,文件地址位于启动器下的如下位置:

init/environment.json

该文件的规则如下:

{
    "global": {
        "sigma": "Qxw5HDkluJF...",
        "appId": "6c2a902b-db2c-...",
        "appKey": "wRSQWM8GtOugMe4V...",
        "language": "cn",
        "active": true,
        "createdBy": "zero-environment",
        "scope": "vie.app.xc",
        "namespace": "cn.originx.vie.app.xc"
    },
    "application": {
        "name": "vie.app.xc"
    },
    "dictionary": {
        "S_PERM_SET": {
            "type": {
                "系统数据管理": "bacdb62f-0f74-...",
                "业务数据管理": "faabb94c-1151-...",
                "开发实施管理": "50615da8-1a89-...",
                "安全管理": "670565fd-40ea-..."
            }
        },
        "B_BAG": {
            "name": {
                "客户管理": "供应商管理"
            },
            "nameAbbr": {
                "CM": "VM"
            },
            "nameFull": {
                "Customer Management": "Vendor Management"
            }
        }
    },
    "forbidden": {
        "X_MENU": {
            "name": [
                "zero.customer",
                "zero.customer.corporation",
                "zero.customer.account",
                "zero.data.psi.commodity",
                "zero.ssm.data"
            ]
        }
    }
}

上述四种规则说明如下:

节点 说明

global

该节点为一个JsonObject,之中的数据会被复用到每一张数据表,只要存在global中定义的字段,该字段都会被设置成文件中定义的值,多租户、多应用、多语言平台可以直接复用数据模板,为不同应用导入相同的OOB配置。

application

(测试专用)启用测试框架时,该节点可以帮助开发人员模拟应用环境,并定制应用所需的上下文信息。

dictionary

字典全局替换,字典全局替换层级一般为 <TABLE>/<ATTRIBUTE>/,它表示将某个表某个字段中的值替换成自定义的值,可做用户级的配置重定义。如上述示例中:S_PERM_SET 表中的 type 字段一旦出现了 系统数据管理 的文本会被替换成对应的UUID格式。

forbidden

数据过滤器,该节点定义的数据不会被导入到系统中,数据最好是唯一条件,如上述示例中 name 包含的这些类型菜单都不会被导入到系统中,通常是为了屏蔽OOB数据特殊导入而量身定制。

新版已经包含了 路由规划表,所以菜单级别的过滤可以不用在 forbidden 中执行,但其他内容依旧可以在此过滤;路由规划表每个应用的不一样,除了可以过滤路由信息之外,还可以调整路由的具体树型结构,以实现路由的完整规划,系统自动帮助完成调整,结合导入部分的幂等性,可反复执行脚本来完成路由的编排。

扩展:办公协同

Zero Ui中的办公协同,主要针对Office的套件( Word, Excel, PPT,PDF )进行在线的协同浏览/编辑,集成了开源版的 ONLYOFFICE 套件,此套件依赖后端运行一个特殊的文档服务器,所以本文提供开发生产场景下的服务器搭建流程,让开发人员可以完善扩展模块 zero-is / zero-doc文档管理以及文档阅览功能。

ONLYOFFICE

安装教程

根据您自身操作系统需求选择对应的安装教程:

zero doc server install

基本介绍

在搭建文档服务器之前先看看 ONLYOFFICE 产品线( Community / Enterprise / Developer 三种版本):

产品名 含义

Docs

提供平台使用的文档编辑器,可以和内置的文档服务器集成(本章内容)。

DocSpace

提供文档协同专用的在线办公室,侧重于工具。

Workspace

工作空间,您可以在这个空间中做项目管理,直接和项目管理强相关的工作区间。

Connectors

和其他平台集成用的连接器

Apps

各种不同平台对应的终端。

ONLYOFFICE 产品线上会包含 Document Server 以及 Community Server 两个服务端,这两个服务端的区别在于:

  • Document Server:直接和内置 Docs 工具集成专用提供编辑器的服务器,编辑器包括:

    • Document Editor:编辑 Word 文档专用。

    • Spreadsheet Editor:编辑 Excel 文档专用。

    • Presentation Editor:编辑 PPT 文档专用。

    • Form Creator:表单编辑器。

    • PDF reader / converter:PDF阅读器和转换器。

  • Community Server:集成专用服务器,提供了 REST 的 API 接口。

其他额外的内容参考:ONLYOFFICE文档中心

教程中主要使用第一个开源产品 ONLYOFFICE Docs,它是一个开源办公套件,包含了文本文档(Word)、电子表格(Excel)、演示文稿(PPT)的编辑器,功能点如下:

  • 创建、编辑、查看对应的文本文档(Word)、电子表格(Excel)、演示文稿(PPT)

  • 和其他团队成员协同处理文档。

  • 查看PDF、导入/导出PDF。

  • 将文档转换成 Markdown / HTML 等相关格式。

  • 将课本转化成电子书。

6.4 版本开始,Docs 提供了对 Web 应用程序开放平台接口协议( WOPI )的支持(一种 REST 协议),用于将您的应用程序和在线办公室集成,它允许您打开存储在服务器上的文件、编辑、保存它们。

它支持的所有格式包括:DOC, DOCX, ODT, RTF, TXT, PDF, HTML, EPUB, XPS, DjVu, XLS, XLSX, ODS, CSV, PPT, PPTX, ODP

Docker安装

Docker默认指定了 Google DNS 服务器,若您无法从互联网访问,则您需要修改Docker的DNS设置保证您可以访问镜像服务器,如常见的Linux的配置位于 /etc/default/docker 文件中,有几种方法可以解决这个问题:

命令方式

在启动命令中使用 docker_OPTS="--dns 8.8.8.8" 参数。

基于 RPM 的系统

  1. 创建配置文件 /etc/docker/daemon.json 文件,配置内容如下:

    {
        "dns": [ "8.8.8.8" ]
    }
  2. 重启Docker服务

    sudo systemctl restart docker.service
基本命令

若安装了Docker,那么您可以使用如下命令启动:

# 有必要追加 sudo
# 直接启动
docker run -i -t -d -p 5600:80 --restart=always -e JWT_SECRET=my_jwt_secret onlyoffice/documentserver:latest

# 您可以先试用如下命令单拉镜像(省掉运行时的镜像拉取时间)
docker pull onlyoffice/documentserver:latest

7.2 的版本开始,若您没有指定 JWT_SECRET 参数,系统会随机生成,且切换虚拟机(VM)和物理机启动时会重新生成,这会给集成带来一定的问题,所以此处最好您直接使用自定义的值:

  • 使用JWT:-e JWT_SECRET=xxxx

  • 关闭JWT:-e JWT_ENABLED=false

存储分离

ONLYOFFICE 中的所有数据都是存储在指定目录中的:

目录 含义

/var/log/onlyoffice

存储 ONLYOFFICE Docs 的日志数据

/var/www/onlyoffice/Data

存储证书信息

/var/lib/onlyoffice

文件缓存

/var/lib/postgresql

数据库文件

若您想要将这些数据存储到容器之外,您可以使用 -v 选项,最终执行命令如下(端口号使用 31017 ):

# 生成自己的 my_jwt_secret,直接使用 ai str -n 1 -l 36
ai str -n 1 -l 36
# 假设:OaBgxq6UYs6IWBSHdUlMswUDmghZIH2cLmK1

docker run -i -t -d -p 31017:80 --restart=always \
    -v $PWD/app@runtime/doc-office/logs:/var/log/onlyoffice \
    -v $PWD/app@runtime/doc-office/data:/var/www/onlyoffice/Data \
    -v $PWD/app@runtime/doc-office/lib:/var/lib/onlyoffice \
    -v $PWD/app@runtime/doc-office/db:/var/lib/postgresql \
    -e JWT_SECRET=OaBgxq6UYs6IWBSHdUlMswUDmghZIH2cLmK1 onlyoffice/documentserver:latest

若将 Docker 使用在生产环境,强烈建议将数据文件存储到容器之外,这种做法和使用 Docker 运行数据库是一个原理。而在Zero脚手架中,新的文档服务器的规划目录放到启动器的 app@runtime/doc-office 目录下,此处的目录基础规划如:

目录/文件 含义

<app>/app@runtime/doc-office

应用根目录,当前目录使用 ${PWD} 环境变量可以得到绝对路径

<app>/app@runtime/doc-office/logs

对应 /var/log/onlyoffice 日志数据。

<app>/app@runtime/doc-office/data

对应 /var/www/onlyoffice/Data 数据目录。

<app>/app@runtime/doc-office/lib

对应 /var/lib/onlyoffice 文件缓存。

<app>/app@runtime/doc-office/db

对应 /var/lib/postgresql 数据库文件。

Docker-Compose

开发推荐:这种方式可以自己修改配置文件,然后使用 docker-compose 拉起 ONLYOFFICE 的服务,先下载库:

git clone https://github.com/ONLYOFFICE/Docker-DocumentServer

修改项目中的 docker-compose.yml 配置文件(只更改端口号部分)

version: '2'
services:
  onlyoffice-documentserver:
    build:
      context: .
    container_name: onlyoffice-documentserver
    depends_on:
      - onlyoffice-postgresql
      - onlyoffice-rabbitmq
    environment:
      - DB_TYPE=postgres
      - DB_HOST=onlyoffice-postgresql
      - DB_PORT=5432
      - DB_NAME=onlyoffice
      - DB_USER=onlyoffice
      - AMQP_URI=amqp://guest:guest@onlyoffice-rabbitmq
      # Uncomment strings below to enable the JSON Web Token validation.
      #- JWT_ENABLED=true
      #- JWT_SECRET=secret
      #- JWT_HEADER=Authorization
      #- JWT_IN_BODY=true
    ports:
      - '20080:80'                      # 端口映射 20080 -> 80
      - '20443:443'                     # 端口映射 20443 -> 443
    stdin_open: true
    restart: always
    stop_grace_period: 60s
    volumes:
      - /var/www/onlyoffice/Data
      - /var/log/onlyoffice
      - /var/lib/onlyoffice/documentserver/App_Data/cache/files
      - /var/www/onlyoffice/documentserver-example/public/files
      - /usr/share/fonts

  onlyoffice-rabbitmq:
    container_name: onlyoffice-rabbitmq
    image: rabbitmq
    restart: always
    expose:
      - '5672'

  onlyoffice-postgresql:
    container_name: onlyoffice-postgresql
    image: postgres:9.5
    environment:
      - POSTGRES_DB=onlyoffice
      - POSTGRES_USER=onlyoffice
      - POSTGRES_HOST_AUTH_METHOD=trust
    restart: always
    expose:
      - '5432'
    volumes:
      - postgresql_data:/var/lib/postgresql

volumes:
  postgresql_data:

依次执行如下命令:

# 进入目录中,docker-compose.yml 已改过
cd Docker-DocumentServer

# 然后拉起
docker-compose up -d

# 停止使用如下命令
docker-compose down

第一次由于镜像、依赖库下载等各种问题,速度会慢一点(保证您的网络连通性),执行过程中您可以看到如下截图:

zero doc docker compose

Ubuntu

本章提供在 UbuntuUbuntu Server 22.04.3 LTS )上安装的详细流程,此部分内容同时支持开发环境/生产环境

需求

CPU

> 2GHz

RAM(内存)

> 2GB

HDD(硬盘)

> 40GB

SWAP

> 4GB

OS

内核版本超过 3.13(执行 uname -a 查看)

其他库

  • PostgreSQL > 12.9

  • NGINX > 1.3.13

  • libstdc++6 > 4.8.4

  • RabbitMQ

前文中已经配置过 ox.office.cn 域名映射的IP地址,所以本章节所有的配置都配置到此域名下,推荐搭建环境时使用域名替换掉IP,不论是局域网DNS还是伪集群模式,使用域名是最好的方式,以防止IP地址变化导致配置的大规模更新;不仅如此,在搭建 Document Server 的机器上还需要设置如下Host:

域名 含义

ox.server.cn

Zero Ui的运行服务器。

ox.engine.cn

Zero 后端的运行服务器。

ox.office.cn

Document Server文档服务器。

由于实例运行在局域网中,安装配置之前先按如下步骤检查防火墙并关闭:

# 查看防火墙状态
# inactive - 禁用
# active - 启用
sudo ufw status
# 禁用防火墙
sudo ufw disable
依赖库

下边是安装 ONLYOFFICE 所需的依赖库:

备注

libcurl3

一个用于处理网络数据传输的开源库,它提供了一个简单的 API,允许开发人员通过多种协议(如HTTP、FTP、SCP、SFTP等)发送和接收数据。

libxml2

libxml2 是一个用于解析和处理XML(可扩展标记语言)文档的开源库,libxml2 提供了一套功能强大的工具,用于读取、解析、创建和修改XML文档,使开发人员能够在各种应用程序中处理XML数据。

fonts-dejavu

fonts-dejavu 是一个开源字体包,包含了 DejaVu 字体系列的字体文件,这些字体是基于 Bitstream Vera 字体系列的扩展,旨在提供广泛的字符集支持,包括拉丁字母、希腊字母、西里尔字母以及各种特殊字符和符号。

fonts-liberation

fonts-liberation 是一个字体包,旨在提供一组兼容微软字体的开源替代品,这些字体与微软的字体(例如Times New Roman、Arial和Courier New)在外观和排版上非常相似,但它们是自由和开源的,可以在各种操作系统上自由使用、分发和修改。

ttf-mscorefonts-installer

ttf-mscorefonts-installer 是一个用于在Linux系统上安装微软核心字体(Microsoft Core Fonts)的软件包,微软核心字体是一组由微软创建并在其操作系统中广泛使用的字体,包括常见的字体如Arial、Times New Roman、Courier New等。

fonts-crosextra-carlito

fonts-crosextra-carlito 是一种字体包,提供了 Carlito 字体,这是对微软 Calibri 字体的开源替代品,Calibri 是一种常见的无衬线字体,通常用于文档和电子邮件等办公应用程序中。

fonts-takao-gothic

fonts-takao-gothic 是一个字体包,包含了 Takao 字体家族的高丽字体(Gothic)变种。Takao 字体是一组用于支持多种亚洲语言字符集的开源字体。

fonts-opensymbol

fonts-opensymbol 是一个字体包,包含了开源的 OpenSymbol 字体。OpenSymbol 字体是一种特殊的字体,用于显示各种符号、图标和特殊字符,通常与办公套件和文档处理软件一起使用。

执行如下命令安装上述库:

# 1. libcurl3 已经没有提供安装源了,所以此处使用 libcurl4 替换
# 2. 此处执行时需使用 sudo 提升权限
sudo apt install libcurl4 libxml2 fonts-dejavu fonts-liberation ttf-mscorefonts-installer fonts-crosextra-carlito fonts-takao-gothic fonts-opensymbol

按照官方教程提及,若安装的是 14.04 TLS 或旧版本才需安装上述依赖库,但由于部分内容已经存在更新包,所以依旧执行一次上述命令,当您看到如下信息证明依赖库已全部安装完成:

zero doc dep

PostgreSQL

ONLYOFFICE 依赖 PgSQL 数据库,本章节提供 PgSQL 在 Ubuntu 上的安装。

  1. 执行下边命令先安装 PgSQL 数据库:

    sudo apt-get install postgresql
  2. 安装完成后,您需要为 ONLYOFFICE 初始化数据库:

    sudo -i -u postgres psql -c "CREATE USER onlyoffice WITH PASSWORD 'onlyoffice';"
    sudo -i -u postgres psql -c "CREATE DATABASE onlyoffice OWNER onlyoffice;"
  3. (局域网访问)编辑 PgSQL 的配置文件:

    1) postgresql.conf 编辑

    sudo vim /etc/postgresql/14/main/postgresql.conf

    找到配置文件中的如下配置,并更改:

    listen_addresses = '*'

    2) pg_hba.conf 编辑

    sudo vim /etc/postgresql/14/main/pg_hba.conf

    在配置文件末尾追加如下:

    # Local Network connect on [ADDRESS] section
    host    all             all             0.0.0.0/0               scram-sha-256

    3)重启服务

    更改配置文件之后,执行如下命令:

    sudo systemctl restart postgresql
  4. 打开数据库连接工具,并使用 onlyoffice/onlyoffice 账号密码访问(确认可连接即可):

    zero doc pg

RabbitMQ

RabbitMQ 是一个开源的消息队列中间件(Message Broker),它实现了高级消息队列协议(AMQP)的标准,消息队列是一种用于在不同的应用程序或组件之间传递消息的通信方式,它们通常用于解耦不同部分的应用程序,以便它们可以独立运行和扩展。

您可以按照如下步骤搭建 Ubuntu 上的 MQ:

  1. 由于 RabbitMQ 依赖 Erlang 语言环境的支持,所以先要安装 Erlang 环境:

    # 依赖库
    sudo apt install build-essential
    sudo apt install libncurses5-dev
    sudo apt install libssl-dev
    sudo apt install unixodbc unixodbc-dev
    sudo apt install freeglut3-dev libwxgtk2.8-dev          # Couldn't find any package by glob 'libwxgtk2.8-dev'
    sudo apt install xsltproc
    sudo apt install fop
    sudo apt install tk8.6
    
    # 语言环境(安装完成后执行 `erl`)
    sudo apt install erlang

    这些库的作用如下:

    备注

    build-essential

    一个用于在Linux操作系统上设置开发环境的包集合,它通常用于Debian和Ubuntu等基于Debian的Linux发行版,包括编译器(GCC)、构建工具(Make)、基本开发库(libc)。

    libncurses5-dev

    用于开发基于文本界面的终端应用程序的开发库,它是ncurses库的开发包,通常用于在Linux和类Unix操作系统上创建具有文本用户界面(TUI)的应用程序。

    libssl-dev

    是用于开发与安全套接字层(SSL)和传输层安全性(TLS)相关的应用程序的开发包,这个包通常在Linux和类Unix操作系统上提供,用于支持安全的网络通信。

    m4

    一个用于文本处理的实用工具,通常用于自动化文本文件的生成和转换。

    unixodbc unixodbc-dev

    是与数据库连接相关的库和开发工具,通常在Unix和Unix-like操作系统上使用,它们用于支持在这些操作系统上连接和访问各种数据库管理系统(DBMS)的应用程序。

    freeglut3-dev libwxgtk2.8-dev

    两个不同的开发包,用于开发图形用户界面(GUI)应用程序,通常在Linux和类Unix操作系统上使用。

    xsltproc

    一个命令行工具,用于处理XML文档并执行XSLT(Extensible Stylesheet Language Transformations)转换。

    fop

    一个开源的Java应用程序,用于将XSL-FO(Extensible Stylesheet Language - Formatting Objects)文档转换为PDF和其他输出格式,XSL-FO是一种XML格式,用于描述文档的外观和格式化要求,包括字体、排版、页眉、页脚、段落和表格等。

    tk8.6

    Tcl/Tk图形用户界面(GUI)工具包的一个特定版本,Tcl(Tool Command Language)是一种脚本编程语言,而Tk是一个用于创建图形用户界面的工具包。

  2. RabbitMQ 的安装和状态查看:

    # 安装
    sudo apt install rabbitmq-server
    # 状态查看
    sudo systemctl status rabbitmq-server
    # < 18.04+, 执行如下
    sudo apt install nginx-extras
  3. RabbitMQ 的日志信息查看:

    直接进入日志目录查看日志信息:

    cd /var/log/rabbitmq/

    zero doc rmqlog

    将带有 rabbit@ 前缀的日志打开(后边跟 host 名),您可以看到当前服务是否查找到对应配置目录:

    zero doc rmqss

  4. RabbitMQ 配置局域网访问(由于关闭了防火墙,所以不需要相关设置,生产环境不推荐):

    cd /etc/rabbitmq/
    vim rabbitmq.config
    # 内容:[{rabbit, [{loopback_users, []}]}].
    # 注意上述配置中最后一个英文句点 . 不可以丢,若丢了会导致启动失败
    
    # 修改完成后重启
    sudo systemctl restart rabbitmq-server

    此处配置的 [{rabbit, [{loopback_users, []}]}]. 意思是开放使用,rabbitmq 默认创建用户 guest,密码也是 guest,值允许 localhost 访问,若要外部访问则必须加上上述配置。

  5. 安装管理平台,安装之后重启:

    sudo rabbitmq-plugins list                          # 查看目前有的插件列表
    sudo rabbitmq-plugins enable rabbitmq_management    # 启用管理平台

    zero doc rmanage

  6. 重启完成之后浏览器打开:http://ox.office.cn:15672/(此处的 ox.office.cn 已经在前边章节配置了),账号密码使用 guest/guest

    zero doc mqgui

ONLYOFFICE Docs

安装 Docs 之前,您需要先看看此产品的端口相关内容,参考如下表格(完整版参考:Ports List):

端口号 服务

80

HTTP

443

HTTPS

4369

Erlang

5432

PostgreSQL

5672

RabbitMQ

6379

Redis

8000

DocService

8080

Spellchecker

若您想要更改 debconf 系统的默认端口,则您可以执行如下命令:

# Zero Framework 中推荐端口号 5600
echo onlyoffice-documentserver onlyoffice/ds-port select <PORT_NUMBER> | sudo debconf-set-selections

如果您想将 ONLYOFFICE Docs 协议更改为 HTTPS,请不要将端口更改为 443,而是参考官方的专用说明:Switching to HTTPS Protocol

参考如下步骤安装 Docs

  1. 添加 GPG Key

    mkdir -p -m 700 ~/.gnupg
    
    curl -fsSL https://download.onlyoffice.com/GPG-KEY-ONLYOFFICE | gpg --no-default-keyring --keyring gnupg-ring:/tmp/onlyoffice.gpg --import
    
    chmod 644 /tmp/onlyoffice.gpg
    
    sudo chown root:root /tmp/onlyoffice.gpg
    
    sudo mv /tmp/onlyoffice.gpg /usr/share/keyrings/onlyoffice.gpg
  2. 追加 ONLYOFFICE Docs 的库:

    echo "deb [signed-by=/usr/share/keyrings/onlyoffice.gpg] https://download.onlyoffice.com/repo/debian squeeze main" | sudo tee /etc/apt/sources.list.d/onlyoffice.list
  3. 更新包缓存:

    sudo apt update

    zero doc deb

  4. 执行如下命令安装

    # Fonts(依赖项部分已安装)
    sudo apt install ttf-mscorefonts-installer
    
    # OnlyOffice(安装过程要提供 PgSQL中的密码)
    sudo apt install onlyoffice-documentserver

其他 Linux 版本如 CentOS 的安装流程,开发人员可参考官方文档和本章提到的步骤自行研究。

JWT

ONLYOFFICE7.2 开始默认会开启 JWT,若您没有为它配置任何密钥 secret,那么它会随机生成一个密钥,若是使用 Docker 模式启动,您可以使用如下两个选项进行配置:

选项 含义

JWT_ENABLED

是否开启 JWT,默认是 true,若想要关闭可以选择 false。

JWT_SECRET

设置 JWT 的值,若此处不设置,则 ONLYOFFICE 会为它随机生成。

安装完成之后,secret 会存储在配置文件 /etc/onlyoffice/documentserver/local.json 中,您可以检查属性 services.CoAuthoring.secret.browser.string。其中 /etc/onlyoffice/documentserver/ONLYOFFICE 的配置目录,此目录中还有一个 default.json 的配置文件,根据官方的教程推荐,配置处理仅编辑 local.json 即可,不要直接编辑 default.json 文件的内容——每次重新启动 Docker 容器或升级 文档服务器 到新版本时都会恢复默认值,并且所有的更改都将丢失。参考如下示例(只和 JWT 相关的部分):

{
    "services": {
        "CoAuthoring": {
            "secret": {
                "inbox": {
                    "string": "secret"
                },
                "outbox": {
                    "string": "secret"
                },
            },
            "token": {
                "enable": {
                    "browser": true,
                    "request": {
                        "inbox": true,
                        "outbox": true
                    }
                }
            }
        }
    }
}

配置 JWT 时需理解如下参数:

参数 含义

services.CoAuthoring.secret.browser.string

Deprecated」定义了在客户端浏览器请求ONLYOFFICE Docs生成令牌的秘钥。自版本 7.2 起请改用 services.CoAuthoring.secret.inbox.string

services.CoAuthoring.secret.inbox.string

自版本 7.2 起,该项定义了在来自文档存储服务到文档命令服务、文档转换服务和文档构建服务的传入HTTP请求中生成令牌的秘钥,以及在客户端浏览器请求ONLYOFFICE Docs时生成令牌的秘钥。

services.CoAuthoring.secret.outbox.string

定义了用于在文档编辑服务发送的传出HTTP请求中生成令牌的秘钥,以供回调URL地址使用。

services.CoAuthoring.token.enable.browser

定义客户端浏览器请求中的令牌是否启用。

services.CoAuthoring.token.enable.request.inbox

定义传入的HTTP请求中的令牌是否启用。

services.CoAuthoring.token.enable.request.outbox

定义传出的HTTP请求中的令牌是否启用。

验证结果

基本环境
  1. 修复配置,若您的配置有问题,可使用如下命令修复:

    zero doc e dpkg

    sudo dpkg --configure -a
    # 下边是输出
    Setting up onlyoffice-documentserver (7.4.1-36) ...
    Generating AllFonts.js, please wait...Done
    Generating presentation themes, please wait...Done
    Generating js caches, please wait...Done
    Installing plugins, please wait...
    # 最后一个步骤十分慢,需要等待很久才可以
  2. 浏览器打开:http://ox.office.cn:5600 地址,您可以看到如下界面,就基本证明:

    zero doc ui

如此您就可以在前端使用 Document Server 了,高级配置可参考官方教程。

诊断/调试

由于修改了配置之后您需要将整个服务重启才可以生效,本章节提供 ONLYOFFICE 的基本命令辅助诊断/调试

  1. 直接进入 /var/log/onlyoffice/documentserver 目录,此目录结构如下:

    文件 含义

    converter/out.log

    Docs Converter 输出日志

    converter/err.log

    Docs Converter 错误日志

    docservice/out.log

    Docs Docservice 输出日志

    docservice/err.log

    Docs Docservice 错误日志

    metrics/out.log

    Docs Metrics 输出日志

    metrics/err.log

    Docs Metrics 错误日志

    nginx.error.log

    Nginx 错误日志

  2. 您可以使用如下命令查看后台服务的状态,默认情况只会安装 Converter / Docservice / Metrics 三个服务:

    # 所有 ONLYOFFICE 安装完成之后的服务都带有 ds- 前缀
    systemctl status ds-*

    zero doc service

  3. 有了上述服务名称之后,您就可以直接使用下边的命令重启服务(大部分场景只需要重启 ds-docservice 服务即可):

    sudo systemctl restart ds-metrics       # Metrics
    sudo systemctl restart ds-docservice    # Docservice
    sudo systemctl restart ds-converter     # Converter
    
    # 参考官方提示
    # RPM / DEB 软件包的重启
    systemctl restart ds-*
    # Docker 安装方式的重启
    supervisorctl restart all

除开上述的内容之外,您还需验证当前文档服务是否可用,按照主界面的操作执行:

# 启动Example服务
sudo systemctl start ds-example
# 随机启动设置
sudo systemctl enable ds-example
  1. 问题一:点击进入主界面,创建一份新文档并且打开:

    zero doc ejwt

    原因一:由于此处您需编辑/上传文档到 Docs 服务器中,若 JWT 未打开则会碰到上述问题,直接编辑配置文件 /etc/onlyoffice/documentserver/local.json,并重启服务。

    {
        "...": "...",
        "enable": {
            "request": {
                "inbox": true,
                "outbox": true
            },
            "browser": true
        }
    }

其他问题遇到了就慢慢收录,参考:Troubleshooting

若您进入 ds-example,就可以看到如下两个界面:

文档列表

zero doc em1

文档编辑

zero doc em2

上述界面证明您的 Document Server 是配置完成了的!

扩展:图引擎

Zero建模的 关系管理 中使用了图引擎(底层使用 neo4j 数据库)来完成关系的维护和搜索,可完成复杂的数据关系的管理和分析,并使用拓扑图呈现出模型之间复杂的关联关系,并提供强大的:基于图的钻取、分析、搜索功能。

环境准备

  1. 先从 neo4j 的官方网站下载对应的安装包信息:

  2. 在项目中开一个专用运行目录:runtime/neo4j(可参考后续步骤截图)。

  3. 准备好 启动脚本停止脚本(注意JDK版本需 > 14):

    neo4j-start.sh

    #!/usr/bin/env bash
    # export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-14.jdk/Contents/Home
    export NEO4J_HOME=$PWD/server
    $NEO4J_HOME/bin/neo4j start

    neo4j-stop.sh

    #!/usr/bin/env bash
    # export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-14.jdk/Contents/Home
    export NEO4J_HOME=$PWD/server
    $NEO4J_HOME/bin/neo4j stop

    :上述环境中每次启动时手动设置了 NEO4J_HOME 的环境变量,若您在操作系统中独立搭建 NEO4J 时,可以将此环境变量设置了系统环境变量中。

  4. 将下载的 tar.gz 解压到 runtime/neo4j/server 目录中:

    # 解压
    tar -zxvf neo4j-community-5.14.0-unix.tar.gz
    # 目录重命名
    mv neo4j-community-5.14.0 server
  5. 最终目录结构如下图:

    zenv n4j rt

配置和启动

  1. 将 APOC 插件拷贝到 plugins 目录中

    APOC 是 Awesome Procedures of Cypher 的缩写,它是 Neo4j 图数据库的扩展过程和函数,提供了丰富的和 查询执行、数据集成、数据库管理 相关的过程和函数,它的功能包括实用程序、转换、图形更新等,可以在 Cypher 中被调用,就像 SQL 中调用存储过程一样,所以有时候也称为 “存储过程”。

    APOC 提供了 450 多个标准程序,包括常用的图算法,它本身是一个二进制的 jar 文件,需单独安装。

    从 5.x 的版本开始,APOC 库已经拆分成了两个独立的包:Core / Extend

    • Core:官方支持的库,包含大多数过程和函数。

    • Extend:社区成员维护的库,包含一些不在 APOC Core 范围内的过程和函数。

    # 官方 APOC
    cp -rf server/labs/apoc-5.14.0-core.jar server/plugins
    # 社区 APOC
    cp -rf plugins/apoc-5.13.0-extended.jar server/plugins
  2. 编辑打开 conf/neo4j.conf 文件,配置 局域网访问 规则(找到对应配置):

    #*****************************************************************
    # Network connector configuration
    #*****************************************************************
    
    # With default configuration Neo4j only accepts local connections.
    # To accept non-local connections, uncomment this line:
    server.default_listen_address=0.0.0.0
    
    # You can also choose a specific network interface, and configure a non-default
    # port for each connector, by setting their individual listen_address.
    
    # The address at which this server can be reached by its clients. This may be the server's IP address or DNS name, or
    # it may be the address of a reverse proxy which sits in front of the server. This setting may be overridden for
    # individual connectors below.
    server.default_advertised_address=ox.integration.cn
  3. 执行启动脚本 neo4j-start.sh

    zenv n4j log

  4. 使用命令 cat server/logs/neo4j.log 查看日志信息:

    2023-12-06 09:16:14.675+0000 INFO  Running in daemon mode, all <Console> appenders will be suppressed:
    2023-12-06 09:16:14.677+0000 INFO  Removing console appender 'ConsoleAppender' with target 'SYSTEM_OUT'.
    2023-12-06 09:16:14.677+0000 INFO  Logging config in use: File '/Users/lang/zero-cloud/web-app/workshop/zero-ws/work-station/runtime/neo4j/server/conf/user-logs.xml'
    2023-12-06 09:16:14.681+0000 INFO  Starting...
    2023-12-06 09:16:15.981+0000 INFO  This instance is ServerId{ad9a81ed} (ad9a81ed-23ba-4096-be80-9d84ed7e225a)
    2023-12-06 09:16:16.294+0000 INFO  ======== Neo4j 5.14.0 ========
    2023-12-06 09:16:19.260+0000 INFO  Called db.clearQueryCaches(): Query cache already empty.
    2023-12-06 09:16:20.332+0000 INFO  Bolt enabled on 0.0.0.0:7687.
    2023-12-06 09:16:20.667+0000 INFO  HTTP enabled on 0.0.0.0:7474.
    2023-12-06 09:16:20.667+0000 INFO  Remote interface available at http://ox.integration.cn:7474/
    2023-12-06 09:16:20.668+0000 INFO  id: F1983EA2C3FAA50E21592172F5327C01ECCA238694CBCD11EE4D3900E24474D7
    2023-12-06 09:16:20.668+0000 INFO  name: system
    2023-12-06 09:16:20.668+0000 INFO  creationDate: 2023-12-06T08:47:24.816Z
    2023-12-06 09:16:20.668+0000 INFO  Started.
  5. 使用浏览器打开:http://ox.integration.cn:7474 ,系统会提示您登录数据库,您可以使用默认账号和密码:neo4j / neo4j,首次登录会让您修改密码:

    登录页

    zenv n4j login

    密码修改页

    zenv n4j pwd

  6. 在浏览器控制台中输入:RETURN apoc.version(),若您的 APOC 没有成功安装,会收到如下错误信息:

    未成功安装

    There is no procedure with the name `apoc.version` registered for this database instance. Please ensure you've spelled the procedure name correctly and that the procedure is properly deployed.

    安装成功

    zenv n4j apoc

如此,您的 Neo4J 图引擎就搭建完成了,记住您在重设密码过程中自己设置的密码,这个密码最终会写入到配置文件中,为了保证您的数据不会被破坏,停止数据库时请使用 neo4j-stop.sh 脚本中的内容来停止,而不是强制退出进程。

扩展:全文检索

ES / Kibana 下载

先从 elasticsearch 的官方网站下载安装包(根据操作系统自己选择安装包)。

Kibana 是 ES 的数据可视化、管理工具,它允许用户以图形化的方式展示 ES 搜哦因中的数据,它的功能表如下:

特征 说明

数据探索

使用 Discover 功能快速搜索和查看 ES 中的数据。

数据可视化

通过 Kibana Lens、Vega 等工具创建丰富图表和可视化效果。

仪表板管理

构建和分享数据仪表板、集成多种可视化组件。

机器学习

利用 ES 的机器学习功能自动检测数据中的异常。

安全性和访问控制

通过基于角色的访问控制 RBAC 和单点登录 SSO 等功能保护数据安全。

Analysis IK 是一个用于中文分词的插件,它提供了两种分词模式:

  • ik_smart:粗粒度拆分,适合做快速概略搜索。

  • ik_max_word:细粒度的拆分,适合做全文检索。

ES 安装

  1. 在项目中开一个专用运行目录:runtime/es

  2. 准备好 启动 脚本(注意JDK版本 >14),ES 的停止可以直接使用 Cmd + C / Ctrl + C

    es-start.sh

    #!/usr/bin/env bash
    # export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-14.jdk/Contents/Home
    # 关闭直接 Ctrl + C
    server/bin/elasticsearch
  3. 将下载的 tar.gz 解压到 runtime/es/server 目录中:

    # 解压
    tar -zxvf elasticsearch-8.11.1-darwin-aarch64.tar.gz
    # 目录重命名
    mv elasticsearch-8.11.1 server
  4. 配置局域网访问,直接编辑配置文件 server/config/elasticsearch.yml

    # ---------------------------------- Network -----------------------------------
    #
    # By default Elasticsearch is only accessible on localhost. Set a different
    # address here to expose this node on the network:
    #
    network.host: 192.168.3.2
  5. 执行下边命令,安装分词插件:Analysis-Ik

    # 注意异常:ERROR: Unknown plugin elasticsearch-analysis-ik-8.11.1.zip, with exit code
    server/bin/elasticsearch-plugin install file://$PWD/elasticsearch-analysis-ik-8.11.1.zip
    
    # 安装过程输出如:
    warning: ignoring JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home; using bundled JDK
    -> Installing file:///Users/lang/zero-cloud/web-app/workshop/zero-ws/work-station/runtime/es/elasticsearch-analysis-ik-8.11.1.zip
    -> Downloading file:///Users/lang/zero-cloud/web-app/workshop/zero-ws/work-station/runtime/es/elasticsearch-analysis-ik-8.11.1.zip
    [=================================================] 100%  
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @     WARNING: plugin requires additional permissions     @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    * java.net.SocketPermission * connect,resolve
    See https://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
    for descriptions of what these permissions allow and the associated risks.
    
    Continue with installation? [y/N]y
    -> Installed analysis-ik
    -> Please restart Elasticsearch to activate any plugins installed

Kibana 安装

  1. 在项目中开一个专用运行目录:runtime/kibana

  2. 将下载的 tar.gz 解压到 runtime/kibana/server 目录中:

    # 解压
    tar -zxvf kibana-8.11.1-darwin-aarch64.tar.gz
    # 目录重命名
    mv kibana-8.11.1 server
  3. 配置局域网访问,直接编辑配置文件 server/config/kibana.yml

    # =================== System: Kibana Server ===================
    # Kibana is served by a back end server. This setting specifies the port to use.
    #server.port: 5601
    
    # Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
    # The default is 'localhost', which usually means remote machines will not be able to connect.
    # To allow connections from remote users, set this parameter to a non-loopback address.
    server.host: "0.0.0.0"

启动/初始化

  1. 关于 ES / Kibana 带安全集成相关配置参考:Secure the Elastic Stack

  2. 直接执行 ES / Kibana 中的启动命令:

    # ES 启动
    server/bin/elasticsearch
    # Kibana 启动
    server/bin/kibana
  3. 启动之后您可以使用:http://ox.integration.cn:5601/ 打开,看到如下界面:

    zenv is kibana

  4. 第一次启动 ES 您是可以直接看到如下信息的:

    ✅ Elasticsearch security features have been automatically configured!
    ✅ Authentication is enabled and cluster connections are encrypted.
    
    ℹ️  Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`):
      <password>
    
    ℹ️  HTTP CA certificate SHA-256 fingerprint:
      <ca-value>
    
    ℹ️  Configure Kibana to use this cluster:
    • Run Kibana and click the configuration link in the terminal when Kibana starts.
    • Copy the following enrollment token and paste it into Kibana in your browser (valid for the next 30 minutes):
    
      <token-value>
    
    ℹ️ Configure other nodes to join this cluster:
    • Copy the following enrollment token and start new Elasticsearch nodes with `bin/elasticsearch --enrollment-token <token>` (valid for the next 30 minutes):
    
      <token-value>
    
      If you're running in Docker, copy the enrollment token and run:
      `docker run -e "ENROLLMENT_TOKEN=<token>" docker.elastic.co/elasticsearch/elasticsearch:8.11.1`
    • <password>:默认的 elastic 账号的密码。

    • <ca-value>:默认的 CA 证书的 fingerprint 值。

    • <token-value>:集成专用的令牌值,前一步中的 token 就应该填写此处的值。

  5. 执行如下命令生成新的 token,填充之后会引导到登录界面:

    server/bin/elasticsearch-create-enrollment-token -s kibana --url "https://192.168.3.2:9200"
    # 将生成的 Token 填到上边步骤窗口中,就可以看到 `elastic` 登录界面
  6. 执行如下命令生成新的密码,用新密码登录:

    server/bin/elasticsearch-reset-password -u elastic
    
    # 输出如下
    warning: ignoring JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home; using bundled JDK
    This tool will reset the password of the [elastic] user to an autogenerated value.
    The password will be printed in the console.
    Please confirm that you would like to continue [y/N]y
    
    
    Password for the [elastic] user successfully reset.
    New value: xxxx
  7. 最终登录主界面如:

    zenv is es web

这样基本的 全文检索 环境就搭建完成了,后续开发过程中就可以在配置中直接连接对应的环境来完成相关功能。